package com.fly.ribbon.config

import com.fly.ribbon.properties.RestTemplateProperties
import org.apache.http.client.HttpClient
import org.apache.http.client.config.RequestConfig
import org.apache.http.config.RegistryBuilder
import org.apache.http.conn.socket.ConnectionSocketFactory
import org.apache.http.conn.socket.PlainConnectionSocketFactory
import org.apache.http.conn.ssl.SSLConnectionSocketFactory
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.context.annotation.Bean
import org.springframework.http.client.ClientHttpRequestFactory
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory
import org.springframework.web.client.RestTemplate

/**
 * @author  fly
 * @date  2021/5/18 16:47
 * @version 1.0
 */
@EnableConfigurationProperties(RestTemplateProperties::class)
class RestTemplateAutoConfigure(private val restTemplateProperties: RestTemplateProperties) {


    @LoadBalanced
    @Bean
    fun restTemplate(): RestTemplate = RestTemplate().apply {
        requestFactory = httpRequestFactory()
    }

    /**
     * httpclient 实现的ClientHttpRequestFactory
     */
    @Bean
    fun httpRequestFactory(): ClientHttpRequestFactory {
        return HttpComponentsClientHttpRequestFactory(httpClient())
    }

    /**
     * 使用连接池的 httpclient
     */
    @Bean
    fun httpClient(): HttpClient = HttpClientBuilder.create()
        .setDefaultRequestConfig(
            RequestConfig.custom()
                .setConnectTimeout(restTemplateProperties.connectTimeout!!)
                .setSocketTimeout(restTemplateProperties.readTimeout!!)
                .setConnectionRequestTimeout(restTemplateProperties.connectTimeout!!)
                .build()
        )
        .setConnectionManager(PoolingHttpClientConnectionManager(

            RegistryBuilder.create<ConnectionSocketFactory>()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build()
        ))
        .setRetryHandler(DefaultHttpRequestRetryHandler(3, true))
        .build()
}